package cn.amossun.starter.common.crypto.rule;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.amossun.starter.common.enums.OutTypeEnum;
import cn.amossun.starter.common.properties.DataSecurityProperties;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;

/**
 * 解密规则
 */
public class DecryptRule extends AbstractRule {

    private static Logger log = Logger.getLogger(DecryptRule.class.toString());

    public DecryptRule(DataSecurityProperties properties) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, UnsupportedEncodingException {
        setCharacterSet(Charset.forName(properties.getCharacterName()));
        setOutType(OutTypeEnum.valueOf(properties.getOutType().toUpperCase()));
        setProperties(properties);
        setOpmode(Cipher.DECRYPT_MODE);
        //setCipher(buildCipher());
    }

    public String getDecryptValue(String originalValue) throws BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, UnsupportedEncodingException {
        if(StrUtil.isEmpty(originalValue)) {
            return originalValue;
        }
        //兼容未含特殊字符加密数据
        if(decryptConfigExists() && !isDecryptData(originalValue)) {
            return originalValue;
        }
        originalValue = subDataSuffix(originalValue);
        return genericDecryptValue(originalValue);
    }

    public String genericDecryptValue(String originalValue) throws BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, UnsupportedEncodingException {
        if(getOutType() == OutTypeEnum.BASE64) {
            byte[] decrypted = Base64Decoder.decode(originalValue.getBytes(getCharacterSet()));
            return new String(buildCipher().doFinal(decrypted), getCharacterSet());
        }

        if(getOutType() == OutTypeEnum.HEX) {
            byte[] decrypted = HexUtil.decodeHex(String.valueOf(originalValue));
            return new String(buildCipher().doFinal(decrypted), getCharacterSet());
        }
        return originalValue;
    }

    protected String subDataSuffix(String originalValue) {
        if(isDecryptData(originalValue)) {
            //掐头:   删除开头字符串
            originalValue = originalValue.substring(getProperties().getDataBeforeSuffix().length());
            //去尾:   删除末尾字符串
            return originalValue.substring(0, originalValue.length() - getProperties().getDataAfterSuffix().length());
        }
        return originalValue;
    }

}
